package marubinotto.util.velocity; import java.util.ArrayList; import java.util.List; import marubinotto.util.ThreadLocalCache; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.UnhandledException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.oro.text.regex.MalformedPatternException; import org.apache.oro.text.regex.Pattern; import org.apache.oro.text.regex.PatternCompiler; import org.apache.oro.text.regex.Perl5Compiler; import org.apache.oro.text.regex.Perl5Matcher; import org.apache.velocity.app.event.ReferenceInsertionEventHandler; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.RuntimeServicesAware; public class EscapeHtmlFilter implements ReferenceInsertionEventHandler, RuntimeServicesAware { private static Log logger = LogFactory.getLog(EscapeHtmlFilter.class); public static final String KEY_INESCAPABLES = "eventhandler.EscapeHtmlFilter.inescapables"; // Config: inescapables private static PatternCompiler compiler = new Perl5Compiler(); // not thread safe private List<Pattern> inescapablePatterns = new ArrayList<Pattern>(); public void setRuntimeServices(RuntimeServices rs) { String[] inescapables = rs.getConfiguration().getStringArray(KEY_INESCAPABLES); if (inescapables == null) return; this.inescapablePatterns.clear(); for (String pattern : inescapables) { if (StringUtils.isBlank(pattern)) continue; pattern = pattern.trim(); logger.info("Inescapable pattern: " + pattern); try { this.inescapablePatterns.add(compiler.compile(pattern)); } catch (MalformedPatternException e) { throw new UnhandledException(e); } } } public Object referenceInsert(String reference, Object value) { if (value == null) { return ""; } if (value instanceof Inescapable) { return value; } for (Pattern pattern : this.inescapablePatterns) { if (ThreadLocalCache.get(Perl5Matcher.class).contains(reference, pattern)) { return value; } } if (logger.isDebugEnabled()) logger.debug("escaping reference: " + reference); return StringEscapeUtils.escapeHtml(value.toString()); } }